package com.huawang.mdesign.model.service.inter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huawang.business.constants.CommonConstants;
import com.huawang.business.constants.ErrorCode;
import com.huawang.business.dto.ValueSpecificationInfo;
import com.huawang.business.entity.MofDataStore;
import com.huawang.business.exception.AbortExecutionException;
import com.huawang.business.service.model.core.InternalSpecificationService;
import com.huawang.business.service.model.core.InternalUmlService;
import com.huawang.core.definition.mof.UMLDefinitionConstants;
import com.huawang.core.definition.mof.instances.MetaClassInstance;
import com.huawang.core.semantics.entity.persistence.SimulationInstanceRecord;
import com.huawang.core.semantics.entity.queryResult.MofResultContainer;
import com.huawang.core.semantics.entity.queryResult.QueryPropertyForm;
import com.huawang.mdesign.model.service.dto.SimulationCreateDTO;
import com.huawang.mdesign.model.service.util.LogUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Log4j2
public class DataProcessor implements Callable<Integer> {
    private final List<MetaClassInstance> allInstances;

    private final MofDataStore mofDataStore;

    private final String projectId;

    private final InternalUmlService internalUmlService;

    private final InternalSpecificationService internalSpecificationService;

    public static final String SIMULATION_QUERY_DATA = "config/SimulationQueryDataConfig.json";

    public DataProcessor(List<MetaClassInstance> allInstances,
                         MofDataStore mofDataStore,
                         String projectId,
                         InternalUmlService internalUmlService,
                         InternalSpecificationService internalSpecificationService) {
        this.allInstances = allInstances;
        this.mofDataStore = mofDataStore;
        this.projectId = projectId;
        this.internalUmlService = internalUmlService;
        this.internalSpecificationService = internalSpecificationService;
    }

    @Override
    public Integer call() {
        // 处理数据的逻辑
        dealData();
        log.info(Thread.currentThread().getName() + "处理条数" + allInstances.size());
        return allInstances.size();
    }

    private void dealData() {
        final Map<String, Set<String>> allGivenTypes = this.internalUmlService.getGivenTypes(projectId, allInstances);
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Map<String, List<String>>> map = new HashMap<>();
        try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(SIMULATION_QUERY_DATA)) {
            JsonNode rootNode = objectMapper.readTree(stream);
            rootNode.fields().forEachRemaining(entry -> {
                String key = entry.getKey();
                JsonNode valueNode = entry.getValue();
                Map<String, List<String>> valueMap = objectMapper.convertValue(valueNode, Map.class);
                map.put(key, valueMap);
            });
        } catch (IOException e) {
            throw AbortExecutionException.build(ErrorCode.JSON_DATA_PARSE_ERROR, e);
        }

        // 存放所有待查的instance
        List<SimulationCreateDTO> simulationCreateDTOs = fillSimulationCreateDTO(allInstances, allGivenTypes, map);
        QueryPropertyForm allQueryPropertyForm = fillQueryPropertyForm(simulationCreateDTOs);
        fillMofDataStore(allQueryPropertyForm, simulationCreateDTOs, allGivenTypes);
    }

    @NotNull
    private static List<SimulationCreateDTO> fillSimulationCreateDTO(List<MetaClassInstance> instances,
                                                                     Map<String, Set<String>> givenTypeMap,
                                                                     Map<String, Map<String, List<String>>> map) {
        LogUtil.printOnlineLogs("givenTypeMap: {}, map: {}", givenTypeMap, map);
        List<SimulationCreateDTO> simulationCreateDTOS = new LinkedList<>();
        for (MetaClassInstance children : instances) {
            final Set<String> givenTypes = givenTypeMap.get(children.getId());
            final SimulationCreateDTO simulationCreateDTO = new SimulationCreateDTO();
            simulationCreateDTO.setMetaClassInstance(children);
            givenTypes.forEach(it -> {
                final Map<String, List<String>> dataMap = map.get(it);
                if (Objects.isNull(dataMap)) {
                    return;
                }
                fillSimulationCreateDTOPropertyName(dataMap, simulationCreateDTO);
            });
            simulationCreateDTOS.add(simulationCreateDTO);
        }
        return simulationCreateDTOS;
    }

    private static void fillSimulationCreateDTOPropertyName(Map<String, List<String>> dataMap, SimulationCreateDTO simulationCreateDTO) {
        LogUtil.printOnlineLogs("dataMap: ", dataMap);
        if (dataMap.containsKey(CommonConstants.SIMULATION_PROPERTY_NAMES)) {
            simulationCreateDTO.getPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_LIST_PROPERTY_NAMES)) {
            simulationCreateDTO.getListPropertyName().addAll(dataMap.get(CommonConstants.SIMULATION_LIST_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_STRING_PROPERTY_NAMES)) {
            simulationCreateDTO.getStringPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_STRING_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_BOOLEAN_PROPERTY_NAMES)) {
            simulationCreateDTO.getBooleanPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_BOOLEAN_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_INTEGER_PROPERTY_NAMES)) {
            simulationCreateDTO.getIntegerPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_INTEGER_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_DOUBLE_PROPERTY_NAMES)) {
            simulationCreateDTO.getDoublePropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_DOUBLE_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_LIST_STRING_PROPERTY_NAMES)) {
            simulationCreateDTO.getListStringPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_LIST_STRING_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY_NAMES)) {
            simulationCreateDTO.getBooleanPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY_NAMES));
            simulationCreateDTO.getListBooleanPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_LIST_BOOLEAN_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_LIST_INTEGER_PROPERTY_NAMES)) {
            simulationCreateDTO.getListIntegerPropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_LIST_INTEGER_PROPERTY_NAMES));
        }
        if (dataMap.containsKey(CommonConstants.SIMULATION_LIST_DOUBLE_PROPERTY_NAMES)) {
            simulationCreateDTO.getListDoublePropertyNames().addAll(dataMap.get(CommonConstants.SIMULATION_LIST_DOUBLE_PROPERTY_NAMES));
        }
    }

    @NotNull
    private static QueryPropertyForm fillQueryPropertyForm(List<SimulationCreateDTO> simulationCreateDTOList) {
        LogUtil.printSerializeOnlineLogs("simulationCreateDTOList: ", simulationCreateDTOList);
        QueryPropertyForm allQueryPropertyForm = new QueryPropertyForm();
        for (SimulationCreateDTO simulationCreateDto : simulationCreateDTOList) {
            List<String> properties = new LinkedList<>();
            properties.addAll(simulationCreateDto.getPropertyNames());
            properties.addAll(simulationCreateDto.getListPropertyName());
            properties.addAll(simulationCreateDto.getStringPropertyNames());
            properties.addAll(simulationCreateDto.getBooleanPropertyNames());
            properties.addAll(simulationCreateDto.getIntegerPropertyNames());
            properties.addAll(simulationCreateDto.getDoublePropertyNames());
            properties.addAll(simulationCreateDto.getListStringPropertyNames());
            properties.addAll(simulationCreateDto.getListBooleanPropertyNames());
            properties.addAll(simulationCreateDto.getListIntegerPropertyNames());
            properties.addAll(simulationCreateDto.getListDoublePropertyNames());
            if (CollectionUtils.isNotEmpty(properties)) {
                allQueryPropertyForm.add(simulationCreateDto.getMetaClassInstance(), properties);
            }
        }
        return allQueryPropertyForm;
    }

    private void fillMofDataStore(QueryPropertyForm queryPropertyForm, List<SimulationCreateDTO> simulationCreateDTOList,
                                  Map<String, Set<String>> givenTypeMap) {
        LogUtil.printSerializeOnlineLogs("simulationCreateDTOList: {}, givenTypeMap: {}", simulationCreateDTOList,
                givenTypeMap);
        if (!queryPropertyForm.getPropertyMap().isEmpty()) {
            // 查询所有数据
            long currentTimeMillis = System.currentTimeMillis();
            final MofResultContainer container = this.internalUmlService.queryProperty(projectId, queryPropertyForm);
            log.info("queryProperty消耗时间：{}", System.currentTimeMillis() - currentTimeMillis);
            // 查询各个instance的数据并放入mofDataStore
            for (SimulationCreateDTO children : simulationCreateDTOList) {
                String instanceId = children.getMetaClassInstance().getId();
                Map<String, String> childrenInstancePropertyMap = new ConcurrentHashMap<>();
                Map<String, List<String>> childrenListInstancePropertyMap = new ConcurrentHashMap<>();
                Map<String, String> childrenStringPropertyMap = new ConcurrentHashMap<>();
                Map<String, Boolean> childrenBooleanPropertyMap = new ConcurrentHashMap<>();
                Map<String, Integer> childrenIntegerPropertyMap = new ConcurrentHashMap<>();
                Map<String, Double> childrenDoublePropertyMap = new ConcurrentHashMap<>();
                Map<String, List<String>> childrenListStringPropertyMap = new ConcurrentHashMap<>();
                Map<String, List<Boolean>> childrenListBooleanPropertyMap = new ConcurrentHashMap<>();
                Map<String, List<Integer>> childrenListIntegerPropertyMap = new ConcurrentHashMap<>();
                Map<String, List<Double>> childrenListDoublePropertyMap = new ConcurrentHashMap<>();

                final Set<String> propertyNames = children.getPropertyNames();
                final Set<String> listPropertyName = children.getListPropertyName();
                final Set<String> stringPropertyNames = children.getStringPropertyNames();
                final Set<String> booleanPropertyNames = children.getBooleanPropertyNames();
                final Set<String> integerPropertyNames = children.getIntegerPropertyNames();
                final Set<String> doublePropertyNames = children.getDoublePropertyNames();
                final Set<String> listStringPropertyNames = children.getListStringPropertyNames();
                final Set<String> listBooleanPropertyNames = children.getListBooleanPropertyNames();
                final Set<String> listIntegerPropertyNames = children.getListIntegerPropertyNames();
                final Set<String> listDoublePropertyNames = children.getListDoublePropertyNames();

                queryAndSetSingleInstanceProperty(container, propertyNames, instanceId, childrenInstancePropertyMap,
                        mofDataStore.getInstanceMap(), childrenStringPropertyMap);
                queryAndSetListInstanceProperty(container, listPropertyName, instanceId, childrenListInstancePropertyMap,
                        mofDataStore.getInstanceMap());
                queryAndSetStringInstanceProperty(container, stringPropertyNames, instanceId, childrenStringPropertyMap);
                queryAndSetBooleanInstanceProperty(container, booleanPropertyNames, instanceId, childrenBooleanPropertyMap);
                queryAndSetIntegerInstanceProperty(container, integerPropertyNames, instanceId, childrenIntegerPropertyMap);
                queryAndSetDoubleInstanceProperty(container, doublePropertyNames, instanceId, childrenDoublePropertyMap);
                queryAndSetListStringProperty(container, listStringPropertyNames, instanceId, childrenListStringPropertyMap);
                queryAndSetListBooleanProperty(container, listBooleanPropertyNames, instanceId, childrenListBooleanPropertyMap);
                queryAndSetListIntegerProperty(container, listIntegerPropertyNames, instanceId, childrenListIntegerPropertyMap);
                queryAndSetListDoubleProperty(container, listDoublePropertyNames, instanceId, childrenListDoublePropertyMap);

                mofDataStore.getInstanceMap().put(instanceId, buildInstanceToRecord(children.getMetaClassInstance()));

                fillSingleInstanceMofDataStore(childrenInstancePropertyMap, instanceId);
                fillMultipleInstanceMofDataStore(childrenListInstancePropertyMap, instanceId);
                fillSingleStringMofDataStore(childrenStringPropertyMap, instanceId);
                fillSingleBooleanMofDataStore(childrenBooleanPropertyMap, instanceId);
                fillSingleIntegerMofDataStore(childrenIntegerPropertyMap, instanceId);
                fillSingleDoubleMofDataStore(childrenDoublePropertyMap, instanceId);
                fillMultipleStringMofDataStore(childrenListStringPropertyMap, instanceId);
                fillMultipleBooleanMofDataStore(childrenListBooleanPropertyMap, instanceId);
                fillMultipleIntegerMofDataStore(childrenListIntegerPropertyMap, instanceId);
                fillMultipleDoubleMofDataStore(childrenListDoublePropertyMap, instanceId);

                if (UMLDefinitionConstants.Enumeration.equals(children.getMetaClassInstance().getClassifier().getId())) {
                    final List<MetaClassInstance> ownedLiteral = container.queryListInstanceProperty(instanceId, UMLDefinitionConstants.Enumeration_ownedLiteral);
                    final Map<String, String> ownedLiteralMap = ownedLiteral.stream().collect(Collectors.toMap(MetaClassInstance::getId, MetaClassInstance::getId, (a, b) -> b));
                    mofDataStore.getEnumLiteralMap().put(instanceId, ownedLiteralMap);
                }
                final Set<String> givenTypes = givenTypeMap.get(instanceId);
                final List<MetaClassInstance> appliedStereotype = container.queryListInstanceProperty(instanceId, UMLDefinitionConstants.Element_appliedStereotype);
                if (CollectionUtils.isNotEmpty(appliedStereotype)) {
                    List<String> appliedStereotypeIds = appliedStereotype.stream().map(MetaClassInstance::getId).collect(Collectors.toList());
                    givenTypes.addAll(appliedStereotypeIds);
                }
                mofDataStore.getInstanceTypeMap().put(instanceId, givenTypes);
            }
        }
    }


    private static void queryAndSetListDoubleProperty(MofResultContainer container, Set<String> listDoublePropertyNames,
                                                      String instanceId, Map<String, List<Double>> listDoublePropertyMap) {
        LogUtil.printOnlineLogs("listDoublePropertyNames: {}, instanceId: {}, listDoublePropertyMap: {}",
                listDoublePropertyNames, instanceId, listDoublePropertyMap);
        listDoublePropertyNames.forEach(propertyName -> {
            final List<Double> properties = container.queryListDoubleProperty(instanceId, propertyName);
            listDoublePutWhileNotEmpty(listDoublePropertyMap, propertyName, properties);
        });
    }

    private static void queryAndSetListIntegerProperty(MofResultContainer container, Set<String> listIntegerPropertyNames,
                                                       String instanceId, Map<String, List<Integer>> listIntegerPropertyMap) {
        LogUtil.printOnlineLogs("listIntegerPropertyNames: {}, instanceId: {}, listIntegerPropertyMap: {}",
                listIntegerPropertyNames, instanceId, listIntegerPropertyMap);
        listIntegerPropertyNames.forEach(propertyName -> {
            final List<Integer> properties = container.queryListIntegerProperty(instanceId, propertyName);
            listIntegerPutWhileNotEmpty(listIntegerPropertyMap, propertyName, properties);
        });
    }

    private static void queryAndSetListBooleanProperty(MofResultContainer container, Set<String> listBooleanPropertyNames,
                                                       String instanceId, Map<String, List<Boolean>> listBooleanPropertyMap) {
        LogUtil.printOnlineLogs("listBooleanPropertyNames: {}, instanceId: {}, listBooleanPropertyMap: {}",
                listBooleanPropertyNames, instanceId, listBooleanPropertyMap);
        listBooleanPropertyNames.forEach(propertyName -> {
            final List<Boolean> properties = container.queryListBooleanProperty(instanceId, propertyName);
            listBooleanPutWhileNotEmpty(listBooleanPropertyMap, propertyName, properties);
        });
    }

    private static void queryAndSetListStringProperty(MofResultContainer lsitStringPropertyContainer, Set<String> listStringPropertyNames,
                                                      String instanceId, Map<String, List<String>> listStringPropertyMap) {
        LogUtil.printOnlineLogs("listStringPropertyNames: {}, instanceId: {}, listStringPropertyMap: {}",
                listStringPropertyNames, instanceId, listStringPropertyMap);
        listStringPropertyNames.forEach(propertyName -> {
            final List<String> properties = lsitStringPropertyContainer.queryListStringProperty(instanceId, propertyName);
            listStringPutWhileNotEmpty(listStringPropertyMap, propertyName, properties);
        });
    }


    private static void queryAndSetDoubleInstanceProperty(MofResultContainer doublePropertyContainer, Set<String> doublePropertyNames,
                                                          String instanceId, Map<String, Double> doublePropertyMap) {
        LogUtil.printOnlineLogs("doublePropertyNames: {}, instanceId: {}, doublePropertyMap: {}",
                doublePropertyNames, instanceId, doublePropertyMap);
        doublePropertyNames.forEach(propertyName -> {
            final Double property = doublePropertyContainer.queryDoubleProperty(instanceId, propertyName);
            if (!Objects.isNull(property)) {
                doublePropertyMap.put(propertyName, property);
            }
        });
    }

    private static void queryAndSetBooleanInstanceProperty(MofResultContainer booleanPropertyContainer, Set<String> booleanPropertyNames,
                                                           String instanceId, Map<String, Boolean> booleanPropertyMap) {
        LogUtil.printOnlineLogs("booleanPropertyNames: {}, instanceId: {}, booleanPropertyMap: {}",
                booleanPropertyNames, instanceId, booleanPropertyMap);
        booleanPropertyNames.forEach(propertyName -> {
            final Boolean property = booleanPropertyContainer.queryBooleanProperty(instanceId, propertyName);
            // 只把true返回，减少json数据量
            if (Boolean.TRUE.equals(property)) {
                booleanPropertyMap.put(propertyName, true);
            }
        });
    }

    private static void queryAndSetIntegerInstanceProperty(MofResultContainer integerPropertyContainer, Set<String> integerPropertyNames,
                                                           String instanceId, Map<String, Integer> integerPropertyMap) {
        LogUtil.printOnlineLogs("integerPropertyNames: {}, instanceId: {}, integerPropertyMap: {}",
                integerPropertyNames, instanceId, integerPropertyMap);
        integerPropertyNames.forEach(propertyName -> {
            final Integer property = integerPropertyContainer.queryIntegerProperty(instanceId, propertyName);
            if (!Objects.isNull(property)) {
                integerPropertyMap.put(propertyName, property);
            }
        });
    }


    private static void queryAndSetStringInstanceProperty(MofResultContainer stringPropertyContainer, Set<String> stringPropertyNames,
                                                          String instanceId, Map<String, String> stringPropertyMap) {
        LogUtil.printOnlineLogs("stringPropertyNames: {}, instanceId: {}, stringPropertyMap: {}",
                stringPropertyNames, instanceId, stringPropertyMap);
        stringPropertyNames.forEach(propertyName -> {
            final String property = stringPropertyContainer.queryStringProperty(instanceId, propertyName);
            if (!Objects.isNull(property)) {
                stringPropertyMap.put(propertyName, property);
            }
        });
    }

    private void queryAndSetSingleInstanceProperty(@NotNull final MofResultContainer mofResultContainer,
                                                   @NotNull final Set<String> propertyNames,
                                                   @NotNull final String instanceId,
                                                   @NotNull final Map<String, String> instancePropertyMap,
                                                   @NotNull final Map<String, SimulationInstanceRecord> instanceMap,
                                                   @NotNull final Map<String, String> childrenStringPropertyMap) {
        LogUtil.printOnlineLogs("propertyNames: {}, instanceId: {}", propertyNames, instanceId);
        // 批量执行queryValueFromValueSpecification
        List<MetaClassInstance> propertyInstances = propertyNames.stream().map(propertyName -> {
            final MetaClassInstance property = mofResultContainer.queryInstanceProperty(instanceId, propertyName);
            if ((propertyName.equals(UMLDefinitionConstants.DurationInterval_min)
                    || propertyName.equals(UMLDefinitionConstants.DurationInterval_max)
                    || propertyName.equals(UMLDefinitionConstants.TimeInterval_min)
                    || propertyName.equals(UMLDefinitionConstants.TimeInterval_max))
                    && Objects.nonNull(property)) {
                return property;
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        Map<String, ValueSpecificationInfo> valueSpecificationInfoMap = this.internalSpecificationService.queryValueFromValueSpecification(projectId, propertyInstances);
        // 根据valueSpecificationInfoMap 组装childrenStringPropertyMap
        propertyNames.forEach(propertyName -> {
            final MetaClassInstance property = mofResultContainer.queryInstanceProperty(instanceId, propertyName);
            if ((propertyName.equals(UMLDefinitionConstants.DurationInterval_min)
                    || propertyName.equals(UMLDefinitionConstants.DurationInterval_max)
                    || propertyName.equals(UMLDefinitionConstants.TimeInterval_min)
                    || propertyName.equals(UMLDefinitionConstants.TimeInterval_max))
                    && Objects.nonNull(property)) {
                final ValueSpecificationInfo valueSpecificationInfo = valueSpecificationInfoMap.get(property.getId());
                if (Objects.nonNull(valueSpecificationInfo.getValue())) {
                    childrenStringPropertyMap.put(propertyName, String.valueOf(valueSpecificationInfo.getValue()));
                }
            }
            mapPutWhileNotEmpty(instancePropertyMap, propertyName, property, instanceMap);
        });
    }

    private static void queryAndSetListInstanceProperty(MofResultContainer receiveSigContainer, Set<String> listPropertyNames,
                                                        String instanceId, Map<String, List<String>> listInstancePropertyMap,
                                                        Map<String, SimulationInstanceRecord> instanceMap) {
        LogUtil.printOnlineLogs("listPropertyNames: {}, instanceId: {}, listInstancePropertyMap: {}, instanceMap: {}",
                listPropertyNames, instanceId, listInstancePropertyMap, instanceMap);
        listPropertyNames.forEach(propertyName -> {
            final List<MetaClassInstance> propertyList = receiveSigContainer.queryListInstanceProperty(instanceId, propertyName);
            listMapPutWhileNotEmpty(listInstancePropertyMap, propertyName, propertyList, instanceMap);
        });
    }

    private static void listMapPutWhileNotEmpty(Map<String, List<String>> map, String key, List<MetaClassInstance> metaClassInstances,
                                                Map<String, SimulationInstanceRecord> instanceMap) {
        LogUtil.printOnlineLogs("map: {}, key: {}", map, key);
        if (CollectionUtils.isNotEmpty(metaClassInstances)) {
            List<String> values = metaClassInstances.stream().map(MetaClassInstance::getId).collect(Collectors.toList());
            map.put(key, values);
            metaClassInstances.forEach(metaClassInstance -> instanceMap.put(metaClassInstance.getId(), buildInstanceToRecord(metaClassInstance)));
        }
    }

    private static void mapPutWhileNotEmpty(Map<String, String> map, String key, MetaClassInstance metaClassInstance,
                                            Map<String, SimulationInstanceRecord> instanceMap) {
        LogUtil.printOnlineLogs("map: {}, key: {}", map, key);
        if (!Objects.isNull(metaClassInstance)) {
            map.put(key, metaClassInstance.getId());
            instanceMap.put(metaClassInstance.getId(), buildInstanceToRecord(metaClassInstance));
        }
    }

    private static void listDoublePutWhileNotEmpty(Map<String, List<Double>> map, String propertyName, List<Double> properties) {
        LogUtil.printOnlineLogs("listDoublePutWhileNotEmpty -> map: {}, propertyName: {}, properties: {})", map, propertyName,
                properties);
        if (CollectionUtils.isNotEmpty(properties)) {
            map.put(propertyName, properties);
        }
    }

    private static void listIntegerPutWhileNotEmpty(Map<String, List<Integer>> map, String propertyName, List<Integer> properties) {
        LogUtil.printOnlineLogs("listIntegerPutWhileNotEmpty -> map: {}, propertyName: {}, properties: {})", map, propertyName,
                properties);
        if (CollectionUtils.isNotEmpty(properties)) {
            map.put(propertyName, properties);
        }
    }

    private static void listBooleanPutWhileNotEmpty(Map<String, List<Boolean>> map, String propertyName, List<Boolean> properties) {
        LogUtil.printOnlineLogs("listBooleanPutWhileNotEmpty -> map: {}, propertyName: {}, properties: {})", map, propertyName,
                properties);
        if (CollectionUtils.isNotEmpty(properties)) {
            map.put(propertyName, properties);
        }
    }

    private static void listStringPutWhileNotEmpty(Map<String, List<String>> map, String propertyName, List<String> properties) {
        LogUtil.printOnlineLogs("listStringPutWhileNotEmpty -> map: {}, propertyName: {}, properties: {})", map, propertyName,
                properties);
        if (CollectionUtils.isNotEmpty(properties)) {
            map.put(propertyName, properties);
        }
    }

    @NotNull
    public static SimulationInstanceRecord buildInstanceToRecord(final MetaClassInstance metaClassInstance) {
        LogUtil.printOnlineLogs("---buildInstanceToRecord---", "metaClassInstance");
        if (metaClassInstance == null) {
            return new SimulationInstanceRecord();
        } else {
            SimulationInstanceRecord metaClassInstanceRecord = new SimulationInstanceRecord();
            metaClassInstanceRecord.setInstanceId(metaClassInstance.getId());
            metaClassInstanceRecord.setOwnerId(metaClassInstance.getOwnerId());
            return metaClassInstanceRecord;
        }
    }

    private void fillSingleInstanceMofDataStore(Map<String, String> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillSingleInstanceMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getInstancePropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillSingleStringMofDataStore(Map<String, String> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillSingleStringMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getStringPropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillSingleBooleanMofDataStore(Map<String, Boolean> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillSingleBooleanMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getBooleanPropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillSingleIntegerMofDataStore(Map<String, Integer> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillSingleIntegerMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getIntegerPropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillSingleDoubleMofDataStore(Map<String, Double> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillSingleDoubleMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getDoublePropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillMultipleInstanceMofDataStore(Map<String, List<String>> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillMultipleInstanceMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getListInstancePropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillMultipleStringMofDataStore(Map<String, List<String>> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillMultipleStringMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getListStringPropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillMultipleBooleanMofDataStore(Map<String, List<Boolean>> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillMultipleBooleanMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getListBooleanPropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillMultipleIntegerMofDataStore(Map<String, List<Integer>> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillMultipleIntegerMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getListIntegerPropertyMap().put(instanceId, childrenMap);
        }
    }

    private void fillMultipleDoubleMofDataStore(Map<String, List<Double>> childrenMap, String instanceId) {
        LogUtil.printOnlineLogs("fillMultipleDoubleMofDataStore -> childrenMap: {}, instanceId: {}", childrenMap, instanceId);
        if (!childrenMap.isEmpty()) {
            mofDataStore.getListDoublePropertyMap().put(instanceId, childrenMap);
        }
    }
}
